<?php
namespace plugin\admin\app\common\xbuilder\widget;
class NodeTree{

    //目标数组
    protected $target = [];
    // $target = [
    //        ['id' => 1 , 'name' => '1111' , 'pid' => 0],
    //        ['id' => 2 , 'name' => '2222' , 'pid' => 0],
    //        ['id' => 3 , 'name' => '3333' , 'pid' => 1],
    //        ['id' => 4 , 'name' => '4444' , 'pid' => 3],
    //        ['id' => 5 , 'name' => '5555' , 'pid' => 2]
    // ];
    /**
     * 配置数组
     * @var [type]
     */
    protected $config = [
        'id'  => 'id' ,  //id
        'pid' => 'pid',  //父id
        'name' => 'name',
        'children' => 'children'
    ];

    /**
     * 实例化配置参数
     * @param [type] $array  [目标数组]
     * @param [type] $config [配置]
     */
    public function __construct($target = [] , $config = []){

        $this->target = array_merge($this->target , $target );
        $this->config = array_merge($this->config , $config );

    }
    /**
     * 获得数组结构列表
     * @param  integer $id   [description]
     * @param  integer $level [description]
     * @return [type]         [description]
     */
    public function getTreeByList($id = 0){

        $array = [];
        foreach($this->target as $k => $v){
            if($v[$this->config['pid']] == $id){
                unset($this->target[$k]);
                $key = $this->config['children'];
                $v[$key] = $this->getTreeByList($v[$this->config['id']]);
                if(empty($v[$key])){
                    unset($v[$key]);
                }
                $array[] = $v;
            }
        }
        return $array;
    }
    /**
     * 获得所有子节点
     * @param  [type] $id [description]
     * @param  [type] $resType ['id','data','name']
     * @return [type]     [description]
     */
    private $_child = [];
    public function getAllChilds($id = 0, $resType = 'id'){
        foreach($this->target as $k => $v){
            if($v[$this->config['pid']] == $id){
                $map = [
                    'id'=>$v[$this->config['id']],
                    'name'=>$v[$this->config['name']],
                    'data'=>$v,
                ];
                $this->_child[] = $map[$resType];
                $this->getAllChilds($v[$this->config['id']],$resType);
            }
        }
        return $this->_child;
    }
    /**
     * 获取所有父级-所有父，包含自己
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    public function getAllParents($id, $resType = 'id'){
        static $ids = [];
        foreach($this->target as $k => $v){
            if($v[$this->config['id']] == $id){
                $map = [
                    'id'=>$v[$this->config['id']],
                    'name'=>$v[$this->config['name']],
                    'data'=>$v,
                ];
                array_unshift($ids , $map[$resType]);
                if($v['pid'] == 0){
                    break;
                }
                $this->getAllParents($v[$this->config['pid']],$resType);
            }
        }
        return $ids;
    }
    /**
     * 得到子的同级的数组
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    public function getChildBros($id, $resType = 'id'){

        $array = [];
        foreach($this->target as $k => $v){
            if($v[$this->config['pid']] == $id){
                $map = [
                    'id'=>$v[$this->config['id']],
                    'name'=>$v[$this->config['name']],
                    'data'=>$v,
                ];
                $array[] = $map[$resType];
            }
        }
        return $array;
    }
    /**
     * 得到同级数组
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    public function getBros($id, $resType = 'id'){

        $array = [];
        $pid = '';
        //获取pid，这个
        foreach($this->target as $k => $v){
            if($v[$this->config['id']] == $id){
                $pid = $v[$this->config['pid']];
                break  1; //退出两层的循环
            }
        }
        if($pid === ''){   //该id不存在，返回空
            return [];
        }
        foreach($this->target as $k => $v){
            if($v[$this->config['pid']] == $pid){
                $map = [
                    'id'=>$v[$this->config['id']],
                    'name'=>$v[$this->config['name']],
                    'data'=>$v,
                ];
                $array[] = $map[$resType];
            }
        }
        return $array;
    }
    /**
     * 得到父级的同级数组
     * @param  [type] $id [description]
     * @return [type]     [description]
     */
    public function getParentBro($id, $resType = 'id'){

        $array = [];
        $pid = '';
        //获取pid，这个
        foreach($this->target as $k => $v){
            if($v[$this->config['id']] == $id){
                $pid = $v[$this->config['pid']];
                break  1; //退出两层的循环
            }
        }
        if($pid === ''){   //该id不存在，返回空

            return [];
        }
        //获取父级的pid
        foreach($this->target as $k => $v){
            if($v[$this->config['id']] == $pid){
                $pid = $v[$this->config['pid']];
                break  1; //退出两层的循环
            }
        }
        if($pid === ''){   //该id不存在，返回空

            return [];
        }
        foreach($this->target as $k => $v){
            if($v[$this->config['pid']] == $pid){
                $map = [
                    'id'=>$v[$this->config['id']],
                    'name'=>$v[$this->config['name']],
                    'data'=>$v,
                ];
                $array[] = $map[$resType];
            }
        }
        return $array;
    }
    /**
     * 得到树形结构
     * @param  [type] $data  [description]
     * @param  string $pid   [description]
     * @param  string $level [description]
     * @return [type]        [description]
     */
    public function getTree($pid = '0',$level = 0){
        static $array = [];
        foreach($this->target as $k => $v){
            if($v[$this->config['pid']] == $pid){
                $v['level'] = $level;
                if($v['level'] == '2'){
                    $v['left'] = str_repeat("&nbsp;&nbsp;",$v['level'])."|--";
                }elseif($v['level'] != '1'){
                    $v['left'] = str_repeat("&nbsp;&nbsp;",$v['level'])."|--".str_repeat('-',$v['level']);
                }else{
                    $v['left'] = '';
                }
                $array[] = $v;
                $this->getTree($v[$this->config['id']],++$v['level']);
            }
        }
        return $array;
    }

    public function where($where = null)
    {
        if (is_string($where)) {
            parse_str($where, $where);
        }
        $list = $this->target;
        // 返回的结果集合
        $resultSet = array();
        foreach ($list as $key => $data) {
            $find = true;

            foreach ($where as $field => $value) {
                if (isset($data[$field])) {
                    if (0 === strpos($value, '/')) {
                        $find = preg_match($value, $data[$field]);
                    } else if ($data[$field] !== $value) {
                        $find = false;
                    }
                }
            }
            if ($find) {
                $resultSet[] = &$list[$key];
            }
        }
        $this->target = $resultSet;
        return $this;
    }

    public function find($where = null){
        if($where){
            $this->where($where);
        }
        return array_reduce($this->target,function ($r,$value){
            return $value;
        });
    }

    public function select($where = null){
        if($where){
            $this->where($where);
        }
        return $this->target;
    }
}
